<template>
  <div class="chat-container">
    <!-- 头部导航 -->
    <van-nav-bar
      title="智能考核"
      left-arrow
      @click-left="backDetails()"
      class="chat-header fixed-header"
    >
    </van-nav-bar>

    <!-- 消息列表 -->
    <div class="message-list" ref="messageListRef">
      <div
        class="message-wrapper"
        v-for="(message, index) in messages"
        :key="index"
      >
        <!-- 时间戳 -->
        <!-- <div class="time-stamp" v-if="shouldShowTime(message, index)">
          {{ formatTime(message.timestamp) }}
        </div> -->

        <!-- 消息气泡 -->
        <div
          class="message-item"
          :class="{
            'message-right': message.type === 'user',
            'message-left': message.type === 'ai',
          }"
        >
          <!-- AI头像 -->
          <div class="avatar" v-if="message.type === 'ai'">
            <van-image
              width="40"
              height="40"
              round
              fit="cover"
              :src="aiAvatar"
              alt="AI助手"
            />
          </div>

          <!-- 消息内容 -->
          <div class="message-bubble" :class="message.type">
            <div class="message-content">
              <div
                v-if="message.type === 'ai' && message.typing"
                class="typing-indicator"
              >
                <span></span>
                <span></span>
                <span></span>
              </div>
              <!-- AI消息使用markdown编辑器 -->
              <div v-else-if="message.type === 'ai'" class="markdownContent">
                <mdEditor
                  :toolbars="[]"
                  :footers="[]"
                  ref="mavonEditor"
                  class="mdEditor"
                  v-model="message.text"
                />
              </div>
              <!-- 用户消息使用v-html -->
              <div
                v-else-if="message.type === 'user'"
                v-html="message.text"
              ></div>
              <div
                class="message-btns"
                v-if="message.type === 'ai' && !isSending"
              >
                <!-- <span class="shuziren"
                  ><img src="@/assets/images/voice-icon.png" alt="数字人讲解" />
                  数字人讲解</span
                > -->
                <span class="copy" @click="copyMessage(message.text)"
                  ><img src="@/assets/images/copy-icon.png" alt="复制" />
                  复制</span
                >
              </div>
            </div>
          </div>

          <!-- 用户头像 -->
          <div class="avatar" v-if="message.type === 'user'">
            <van-image
              width="40"
              height="40"
              round
              fit="cover"
              :src="userAvatar"
              alt="用户"
            />
          </div>
        </div>
      </div>

      <!-- 占位符，用于滚动到底部 -->
      <div ref="scrollAnchor" style="height: 1px"></div>
    </div>

    <!-- 输入区域 -->
    <div class="input-area fixed-input">
      <!-- 输入框 -->
      <div class="input-container">
        <div class="input-wrapper">
          <van-field
            v-model="userInput"
            placeholder="输入消息..."
            type="textarea"
            rows="1"
            autosize
            @keyup.enter="sendMessage"
            class="message-input"
            :disabled="inputDisabled || endStatus === 1"
          />

          <van-button
            :disabled="isSending || inputDisabled || endStatus === 1"
            @click="sendMessage"
            type="primary"
            size="small"
            round
            class="send-btn"
            :loading="isSending"
          >
            <van-icon name="send" v-if="!isSending" />发送
          </van-button>
        </div>
      </div>
    </div>

    <!-- 图片预览 -->
    <!-- <van-image-preview
      v-model:show="showImagePreview"
      :images="previewImages"
      :start-position="previewIndex"
    /> -->
  </div>
</template>

<script>
import aiAvatar from "@/assets/images/lu-icon.png";
import userAvatar from "@/assets/images/stu-icon.png";
export default {
  data() {
    return {
      courseId: "",
      uploadedFiles: [],
      userInput: "",
      messages: [],
      messageRecord: [],
      aiAvatar,
      userAvatar,
      selectedFileIndex: [],
      isSelected: false, // 用于跟踪当前选择状态
      quotedText: "", // 新增引用文本
      uploadLoading: false,
      eventSource: null,
      connectId: null,
      fileId: null,
      isSending: false,
      stopHover: false,
      clearHover: false,
      sessionId: "",
      sseUrl: "",
      videoDialogVisible: false,
      videoData: null,
      sseResource: "", // sse资源数据
      isCollectingJson: false, // 标记是否正在收集JSON数据
      jsonBuffer: "", // 临时存储JSON数据
      kbId: null, // 知识库ID，用于进入考核时传递
      shuzirenPic: "",
      shuzirenPid: "",
      zhuzirenAudio: "",
      inputDisabled: false, // 控制输入框禁用状态
      classId: null,
      chapterId: null,
      endStatus: null, // 结束状态
    };
  },
  watch: {
    "$route.query.chapterId": {
      handler(newVal) {
        this.courseId = JSON.parse(localStorage.getItem("courseId"));
        this.chapterId = newVal;
        this.checkAndGetChatRecord();
      },
      immediate: true, // 立即执行
    },
  },
  created() {
    this.getSessionId();
  },
  methods: {
    // 检查参数并获取聊天记录
    checkAndGetChatRecord() {
      if (this.chapterId) {
        this.getChatRecord();
      }
    },

    // 获取聊天记录
    getChatRecord() {
      const loading = this.$loading({
        lock: true,
        text: "加载中...",
        spinner: "el-icon-loading",
        background: "rgba(0, 0, 0, 0.7)",
      });
      this.$axios
        .get(
          `/tes/course/auto/make/list-record?contextId=${this.chapterId}&courseId=${this.courseId}&type=4&correctAnswer=1`
        )
        .then((res) => {
          this.messageRecord = res.data.record || [];
          this.endStatus = res.data.endStatus;
          // this.$emit("endFn", this.endStatus);
          if (this.messageRecord.length > 0) {
            this.sessionId = res.data.sessionId;
            // 有聊天记录，处理并展示记录
            this.processChatHistory(this.messageRecord);
          } else {
            // 无聊天记录，调用新的对话接口
            this.callDialogueAPI("开始");
          }
        })
        .finally(() => {
          loading.close();
        });
    },

    // 新增：调用对话接口
    callDialogueAPI(prompt) {
      // 获取用户信息
      const userInfo = JSON.parse(localStorage.getItem("userInfo") || "{}");
      const userId = userInfo.id;

      if (!userId) {
        this.$message.error("获取用户信息失败");
        return;
      }

      // 先添加AI消息占位符（仅在开始时）
      if (prompt === "开始") {
        const aiMessage = {
          type: "ai",
          text: "",
          isWelcome: true,
          typing: true,
          videoData: null,
          documents: [],
          sseResource: null,
        };
        this.messages.push(aiMessage);
        this.isSending = true;
      }

      // 建立SSE连接
      this.connectEventSource(() => {
        // 连接建立后调用对话接口
        const requestData = {
          prompt: prompt,
          connectId: this.connectId,
          sessionId: this.sessionId,
          userId: 0,
          agentId: this.chapterId, // 考核id，为左侧列表点击传过来的id
          courseId: this.courseId,
        };

        this.$axios
          .post("/tes/graph/assess-chapter/dialogue-h5", requestData)
          .then((res) => {
            console.log("对话接口调用成功:", res);
          })
          .catch((error) => {
            console.warn("对话接口调用失败:", error);
            this.isSending = false;
          });
      });
    },

    // 处理聊天历史记录
    processChatHistory(records) {
      // 清空当前messages，保留欢迎语之外的内容
      this.messages = [];

      records.forEach((record) => {
        // 处理用户消息
        if (record.role == "user") {
          const userMessage = {
            type: "user",
            text: record.content?.replace(/\n/g, "<br>") || "",
          };
          this.messages.push(userMessage);
        }

        // 处理AI回复消息
        if (record.role == "assistant") {
          const aiMessage = {
            type: "ai",
            text: record.content?.replace(/\\n/g, "<br>") || "",
            files: record.files || [],
            isWelcome: false,
            videoData: record.video || null, // 数字人视频数据
            documents: record.resources || [], // 文档数据
            sseResource: record.sseResource || null, // SSE资源数据
            nextButton: record.nextButton || null, // 下一题按钮
            stopButton: record.stopButton || null, // 停止按钮
            courseTestButton: record.courseTestButton || null, // 进入考核按钮
            courseTestButtonName: record.courseTestButtonName || null, // 进入考核按钮名称
            courseTestButtonId: record.courseTestButtonId || null, // 进入考核按钮id
          };
          this.messages.push(aiMessage);
        }
      });

      // 滚动到最新消息
      this.scrollToBottom();
    },

    getSessionId() {
      const characters =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
      let result = "";
      for (let i = 0; i < 16; i++) {
        result += characters.charAt(
          Math.floor(Math.random() * characters.length)
        );
      }
      this.sessionId = result;
    },

    // 发送消息
    sendMessage() {
      if (this.userInput.trim() === "") {
        this.$message.error("请输入您想问的内容");
        this.userInput = "";
        return;
      }

      if (this.isSending) {
        this.$message.error("请等待上一次对话结束");
        return;
      }

      if (this.inputDisabled || this.endStatus === 1) {
        this.$message.error("当前考核已结束");
        return;
      }

      // 添加user消息
      const newMessage = {
        type: "user",
        quotedText: this.quotedText ? this.quotedText : "",
        text: this.userInput.replace(/\n/g, "<br>"),
        files: this.selectedFileIndex.map((index) => this.uploadedFiles[index]),
      };
      this.messages.push(newMessage);

      // 滚动到底部显示用户消息
      this.scrollToBottom();

      // 添加AI消息占位
      const aiMessage = {
        type: "ai",
        text: "",
        files: [],
        isWelcome: false,
        typing: true,
      };
      this.messages.push(aiMessage);

      // 调用对话接口
      this.callDialogueAPI(this.userInput);

      // 清空输入框和选中的文件
      const currentInput = this.userInput;
      this.userInput = "";
      this.quotedText = "";
      this.isSending = true;

      // 滚动到最新消息
      this.scrollToBottom();
    },

    // 建立sse连接
    connectEventSource(callback) {
      const that = this;

      if (window.EventSource) {
        // 如果已经存在连接，先关闭
        if (this.eventSource) {
          this.eventSource.close();
        }

        // 重置JSON收集状态
        this.isCollectingJson = false;
        this.jsonBuffer = "";
        this.sseResource = "";

        this.eventSource = new EventSource(`/tes/course/auto/make/sse/connect`);

        this.eventSource.onmessage = function (event) {
          const connectId = event.lastEventId;
          const data = event.data;

          if (connectId === data) {
            // 获取到连接id后执行回调
            that.connectId = connectId;
            if (callback) {
              callback();
            }
          } else {
            // 处理返回的消息流
            let currentMessage = that.messages[that.messages.length - 1];

            // 检查是否开始收集JSON数据
            if (data === "↖sseDone↘") {
              that.isCollectingJson = true;
              that.jsonBuffer = "";
              return;
            }

            // 检查是否结束收集JSON数据
            if (data === "↖Done↘") {
              if (that.isCollectingJson) {
                // 处理收集到的JSON数据
                try {
                  const parsedJson = JSON.parse(that.jsonBuffer);
                  that.sseResource = parsedJson;
                  console.log("提取到的JSON资源数据:", parsedJson);

                  // 检查 end 字段，如果为 1 则禁用输入框
                  if (parsedJson.end == 1) {
                    that.inputDisabled = true;
                  }

                  // 将sseResource数据存储到当前AI消息中，同时处理视频和文档资源
                  let currentMessage = that.messages[that.messages.length - 1];
                  if (currentMessage && currentMessage.type === "ai") {
                    currentMessage.sseResource = parsedJson;
                    // 处理视频数据
                    if (parsedJson.video && parsedJson.video.length > 0) {
                      currentMessage.videoData = parsedJson.video;
                    }
                    // 处理文档资源
                    if (
                      parsedJson.resources &&
                      parsedJson.resources.length > 0
                    ) {
                      currentMessage.documents = parsedJson.resources;
                    }
                  }
                } catch (error) {
                  console.warn(
                    "JSON解析失败:",
                    error,
                    "原始数据:",
                    that.jsonBuffer
                  );
                  // 如果解析失败，保存原始字符串
                  that.sseResource = that.jsonBuffer;

                  // 同样存储到当前AI消息中
                  let currentMessage = that.messages[that.messages.length - 1];
                  if (currentMessage && currentMessage.type === "ai") {
                    currentMessage.sseResource = that.jsonBuffer;
                  }
                }

                // 重置收集状态
                that.isCollectingJson = false;
                that.jsonBuffer = "";
              }

              // SSE流结束
              that.isSending = false;
              that.eventSource.close();
              that.eventSource = null;
              return;
            }

            // 如果正在收集JSON数据，将data添加到缓冲区
            if (that.isCollectingJson) {
              that.jsonBuffer += data;
              return;
            }

            // 确保当前消息是AI消息，且不在收集JSON状态
            if (currentMessage && currentMessage.type === "ai") {
              // 取消typing状态
              currentMessage.typing = false;
              // 处理特殊字符
              let processedData = data
                .replaceAll("↖emsp↘", " ")
                .replaceAll("↖Start↘", "")
                .replaceAll("↖br↘", "\n")
                .replaceAll("↖tab↘", "   ")
                .replaceAll("↖sseDone↘", "")
                .replaceAll("↖Done↘", "")
                // 处理每个字符都被双引号包围的情况（如："欢""迎" -> 欢迎）
                .replace(/"(.?)"/g, "$1")
                // 处理被分割的Unicode字符（如："\uD83D""\uDC49" -> \uD83D\uDC49）
                .replace(/"(\\u[0-9A-Fa-f]{4})""(\\u[0-9A-Fa-f]{4})"/g, "$1$2")
                // 处理单独的Unicode字符
                .replace(/"(\\u[0-9A-Fa-f]{4})"/g, "$1")
                // 将Unicode转义序列转换为实际字符（处理代理对）
                .replace(
                  /\\u([0-9A-Fa-f]{4})\\u([0-9A-Fa-f]{4})/g,
                  (match, high, low) => {
                    const highCode = parseInt(high, 16);
                    const lowCode = parseInt(low, 16);
                    // 检查是否为代理对
                    if (
                      highCode >= 0xd800 &&
                      highCode <= 0xdbff &&
                      lowCode >= 0xdc00 &&
                      lowCode <= 0xdfff
                    ) {
                      return String.fromCharCode(highCode, lowCode);
                    }
                    // 否则单独处理每个字符
                    return (
                      String.fromCharCode(highCode) +
                      String.fromCharCode(lowCode)
                    );
                  }
                )
                // 处理单独的Unicode字符
                .replace(/\\u([0-9A-Fa-f]{4})/g, (match, code) => {
                  return String.fromCharCode(parseInt(code, 16));
                })
                // 处理字面的换行符字符串
                .replaceAll('\\"n\\"', "\n")
                .replaceAll('"\\n"', "\n")
                .replaceAll("\\n", "\n")
                // 处理其他转义字符
                .replaceAll("\\t", "\t")
                .replaceAll('\\"', '"');

              // 更新markdown内容
              currentMessage.text += processedData;

              // 滚动到底部
              that.scrollToBottom();
            }
          }
        };

        this.eventSource.onerror = function (error) {
          that.eventSource.close();
          that.eventSource = null;
          that.isSending = false;
        };
      } else {
        this.$message.error("您的浏览器不支持 SSE，请更换浏览器");
        that.isSending = false;
      }
    },

    // 复制消息
    copyMessage(text) {
      try {
        if (navigator.clipboard) {
          navigator.clipboard.writeText(text).then(() => {
            this.$message.success("消息已复制到剪贴板");
          });
        } else {
          // 降级处理 - 使用传统方法
          const textarea = document.createElement("textarea");
          textarea.value = text;
          document.body.appendChild(textarea);
          textarea.select();
          document.execCommand("copy");
          document.body.removeChild(textarea);
          this.$message.success("消息已复制到剪贴板");
        }
      } catch (err) {
        this.$message.error("复制失败，请手动复制");
      }
    },

    // 滚动到底部
    scrollToBottom() {
      this.$nextTick(() => {
        setTimeout(() => {
          const messageList = this.$refs.messageListRef;
          if (messageList) {
            // 强制滚动到最底部，使用 scrollTo 方法更精确
            messageList.scrollTo({
              top: messageList.scrollHeight,
              // behavior: "smooth",
            });
            return;
          }
        }, 200);
      });
    },

    // 换行处理
    handleKeyCode(event) {
      if (event.keyCode === 13) {
        if (event.shiftKey) {
          return;
        } else {
          event.preventDefault();
          this.sendMessage();
        }
      }
    },

    // 返回
    backDetails() {
      this.$router.push({
        path: "/courseDetails",
        query: { chapterId: this.chapterId },
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.chat-container {
  height: 100vh;
  height: 100dvh; /* 动态视口高度，更好地适配移动端 */
  background: #f5f6fb;
  position: relative;
  overflow: hidden; /* 避免出现滚动条 */
}

.chat-header {
  background: #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  --van-nav-bar-title-text-color: #1f2937;
  --van-nav-bar-icon-color: #6b7280;
}

.fixed-header {
  position: fixed;
  top: 0;
  top: env(safe-area-inset-top, 0); /* 适配刘海屏 */
  left: 0;
  right: 0;
  z-index: 1000;
}

.message-list {
  position: absolute;
  top: calc(46px + env(safe-area-inset-top, 0)); /* 导航栏高度 + 安全区域 */
  left: 0;
  right: 0;
  bottom: 0;
  overflow-y: auto;
  padding: 16px 16px 80px; /* 上下边距，为固定输入框留空间 */

  &::-webkit-scrollbar {
    display: none;
  }
}

.message-wrapper {
  margin-bottom: 20px;
}

.time-stamp {
  text-align: center;
  color: #9ca3af;
  font-size: 24px;
  margin-bottom: 16px;
  position: relative;

  &::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 0;
    right: 0;
    height: 1px;
    background: #e5e7eb;
    z-index: 1;
  }

  &::after {
    content: attr(data-time);
    background: #f7f8fc;
    padding: 0 16px;
    position: relative;
    z-index: 2;
  }
}

.message-item {
  display: flex;
  margin-bottom: 16px;
  animation: fadeInUp 0.3s ease;

  &.message-right {
    justify-content: flex-end;

    .message-bubble {
      margin-right: 12px;
    }
  }

  &.message-left {
    justify-content: flex-start;

    .message-bubble {
      margin-left: 12px;
    }
  }
}

.avatar {
  flex-shrink: 0;

  :deep(.van-image) {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    border: 2px solid #fff;
  }
}

.message-bubble {
  max-width: 70%;
  position: relative;

  &.user {
    .message-content {
      background: #dce9ff;
      color: #1f2937;
      border-radius: 10px;
    }
  }

  &.ai {
    .message-content {
      background: #fff;
      color: #1f2937;
      border-radius: 10px;

      .markdownContent {
        .mdEditor {
          border: none;
          height: auto;
          // 隐藏左侧编辑区
          :deep(.md-editor-input-wrapper) {
            display: none;
          }
          // 隐藏中间分割线
          :deep(.md-editor-resize-operate) {
            width: 0;
          }
          :deep(.md-editor-content-wrapper) {
            width: 100% !important;
          }
          :deep(.md-editor-content) {
            display: block;
          }
          :deep(.md-editor-preview) {
            padding: 0;
            p {
              margin: 0;
            }
          }
        }
      }

      .message-btns {
        margin-top: 10px;
        display: flex;
        color: #457aff;
        font-size: 12px;
        cursor: pointer;
        .shuziren {
          margin-right: 20px;
        }
        .copy {
          cursor: pointer;
        }
      }
    }
  }
}

.message-content {
  padding: 12px 16px;
  font-size: 16px;
  line-height: 1.5;
  word-break: break-word;
  position: relative;

  :deep(br) {
    line-height: 1.8;
  }
}

.typing-indicator {
  display: flex;
  align-items: center;
  gap: 4px;

  span {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #d1d5db;
    animation: typing 1.4s infinite ease-in-out;

    &:nth-child(2) {
      animation-delay: 0.2s;
    }

    &:nth-child(3) {
      animation-delay: 0.4s;
    }
  }
}

.input-area {
  background: #fff;
  border-top: 1px solid #f3f4f6;
  padding: 12px;
}

.fixed-input {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 1000;
  background: #fff;
  border-top: 1px solid #f3f4f6;
  padding: 12px;
  padding-bottom: calc(
    12px + env(safe-area-inset-bottom, 0)
  ); /* 底部安全区域适配 */
}

.input-container {
  position: relative;
}

.input-wrapper {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 12px;
  background: #f8fafc;
  border-radius: 24px;
  padding: 8px;
  border: 1px solid #e2e8f0;
  transition: all 0.2s ease;

  &:focus-within {
    border-color: #667eea;
    box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
  }
}

.message-input {
  flex: 1;
  background-color: #f8fafc;
  :deep(.van-field__control) {
    background: transparent;
    border: none;
    resize: none;
    font-size: 16px;
    line-height: 1.5;
    max-height: 120px;

    &::placeholder {
      color: #9ca3af;
    }
  }

  :deep(.van-field__word-limit) {
    font-size: 14px;
    color: #9ca3af;
  }
}

.send-btn {
  background: #457aff;
  flex-shrink: 0;
  min-width: 64px;
  transition: all 0.2s ease;

  &:not(:disabled):active {
    transform: scale(0.95);
  }

  &:disabled {
    opacity: 0.5;
  }
}

// 动画
@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes typing {
  0%,
  60%,
  100% {
    transform: scale(0.8);
    opacity: 0.5;
  }
  30% {
    transform: scale(1);
    opacity: 1;
  }
}

// // 响应式适配
// @media (max-width: 375px) {
//   .message-bubble {
//     max-width: 75%;
//   }

//   .message-content {
//     font-size: 16px;
//     padding: 10px 14px;
//   }

//   .input-area {
//     padding: 12px;
//   }
// }

// // 深色模式适配（可选）
// @media (prefers-color-scheme: dark) {
//   .chat-container {
//     background: linear-gradient(180deg, #1f2937 0%, #111827 100%);
//   }

//   .chat-header {
//     background: #1f2937;
//     --van-nav-bar-title-text-color: #f9fafb;
//     --van-nav-bar-icon-color: #d1d5db;
//   }

//   .message-bubble.ai .message-content {
//     background: #374151;
//     color: #f9fafb;
//     border-color: #4b5563;
//   }

//   .input-wrapper {
//     background: #374151;
//     border-color: #4b5563;
//   }

//   .input-area {
//     background: #1f2937;
//     border-top-color: #4b5563;
//   }
// }
</style>
